#include "mta.h"

using namespace std;

namespace mta{
	MTAData::MTAData(const string& file1, const string& file2){
		//read file1 (MTA data)
		ifstream ifs(file1);
		if(!ifs) {exit(-1);}
		string line;
		while(getline(ifs, line)){
			vTSD.push_back(new trainStopData(line));
			mTSD[vTSD.back()->get_id()] = vTSD.size()-1;
		}

		ifs.close();
		ifs.open(file2);
		if(!ifs) {exit(-1);}
		adjacencyList.resize(vTSD.size());
		while(getline(ifs, line)){
			string a = line.substr(0,3);
			string b = line.substr(4,3);
			if(a != b)
				adjacencyList[ mTSD[a] ].push_back(b);
		}
		adjacencyList[0].push_back(vTSD[3]->get_id());	//hard coded because I know it's true
		for (size_t i = 3; i < adjacencyList.size()-3; ++i)
		{
			if(vTSD[i-3]->get_id()[0] == vTSD[i]->get_id()[0]){	//the one before this is on the right line
				adjacencyList[i].push_back(vTSD[i-3]->get_id());
			}
			if(vTSD[i+3]->get_id()[0] == vTSD[i]->get_id()[0]){	//the one after this is on the right line
				adjacencyList[i].push_back(vTSD[i+3]->get_id());
			}
		}
		adjacencyList[adjacencyList.size()-1].push_back(vTSD[vTSD.size()-4]->get_id());

	}

	trainStopData* MTAData::getById(const std::string& name){
		return (vTSD[mTSD[name]]);
	}

	void MTAData::printAL(){	//should be const but it wont compile because I deen access to a pointer which is not const
		for(size_t i = 0; i < adjacencyList.size(); ++i){
			cout << adjacencyList[i].size() << "  " << *vTSD[i] << endl;
			for(string s : adjacencyList[i]){
				cout << '\t' << *vTSD[mTSD[s]] << endl;
			}
		}
	}

	list<string> MTAData::hereToThere(const std::string& a, const std::string& b){
		queue<string> q;
		map<string, pair<string, int> > prevMap;	//key is the stop ID, pair1 is previuos id, pair2 is distance from a
		//add a's adj list
		q.push(a);
		prevMap[a] = pair<string, int>("", 0);
		//loop over q adding THIER adj lists until I have visited b
		while(!q.empty()){
			//is this b?
			//break
			if(q.front() == b){
				break;
			}
			list<string> adjs = adjacencyList[ mTSD[q.front()] ];
			for(string s  : adjs){
				//see if this place has been visited
				if(prevMap.find(s) == prevMap.end()){	//not visited
					//push adjacencies onto q
					q.push(s);
					//map the adjacencies into prevMap
					prevMap[s] = pair<string, int>(q.front(), prevMap[q.front()].second+1);
				}
			}
			//forgot the pop...
			q.pop();
		}
		//build the syop-by-stop directions
		list<string> resTSD;
		resTSD.push_front(b);
		while(resTSD.front() != a){
			resTSD.push_front( prevMap[ resTSD.front() ].first );
		}

		return resTSD;
	}
}